package bubblesn;
import com.martiansoftware.jsap.*;
// available at http://martiansoftware.com/jsap/

/**
 * Main program class
 * @author Rafalmag
 */
public class BubbleSn {
	/*
	 * variables storing execution options
	 */
	private static int inputs=3;
	private static int threads=1;
	private static boolean map=false;
	private static boolean time=false;
	
	/**
	 * Main program class
	 * @param args - try "--help"
	 */
	public static void main(String[] args) throws Exception{
		argParser(args);

		System.out.println("Bubble");
		try{
			count(new Bubble(inputs));
		}catch(Exception e){
			e.printStackTrace();
		}
		
		System.out.println("\n----------------\n");
		System.out.println("Bubble modified");		
		try {
			count(new BubbleModified(inputs));
		} catch (Exception e) {
			e.printStackTrace();
		}
	}
	
	/**
	 * Parses application input arguments
	 * @param args
	 * @throws Exception
	 */
	private static void argParser(String[] args) throws Exception {
		JSAP jsap = new JSAP();
		
		FlaggedOption in = new FlaggedOption("inputs")
				.setStringParser(JSAP.INTEGER_PARSER)
				//.setDefault("3") 
				.setRequired(true) 
				.setShortFlag('i') 
				.setLongFlag("inputs");
		in.setHelp("Number of inputs");
		
		jsap.registerParameter(in);
		
		FlaggedOption th = new FlaggedOption("threads")
				.setStringParser(JSAP.INTEGER_PARSER)
				.setDefault("1") 
				.setRequired(false) 
				.setShortFlag('t') 
				.setLongFlag("threads");
		th.setHelp("Number of threads");

		jsap.registerParameter(th);
		
		Switch sw1 = new Switch("map")
				.setShortFlag('m')
				.setDefault("false")
				.setLongFlag("print-maps");
		sw1.setHelp("Prints graphical representation of SN");
		jsap.registerParameter(sw1);
		
		Switch sw2 = new Switch("time")
				.setShortFlag('c')
				.setDefault("false")
				.setLongFlag("time");
		sw2.setHelp("Prints computing time");
		jsap.registerParameter(sw2);
		
		Switch sw3 = new Switch("help")
			.setShortFlag('h')
			.setDefault("false")
			.setLongFlag("help");
		sw3.setHelp("Prints this help message.");
		jsap.registerParameter(sw3);
	        
		JSAPResult config = jsap.parse(args);    
		
		
		if (!config.success() || config.getBoolean("help")==true || args.length == 0) {
		    System.err.println();
		    System.err.println("Usage: java -jar bubblesn.jar ");
		    System.err.println("                "+ jsap.getUsage());
		    System.err.println();
            System.err.println(jsap.getHelp());
            System.err.println("Author: Rafal Magda (rafalmag@gmail.com)");
		    System.exit(1);
		}
		
		inputs=config.getInt("inputs");
		threads=config.getInt("threads");
		map=config.getBoolean("map");
		time=config.getBoolean("time");
	}

	/**
	 * Counts path lengths for given Sorting Network.
	 * If map flag is true prints graphical representation of map.
	 * If time flag is true prints algorithm work time. 
	 * @param sn SortingNetwork for which we will compute path lengths.
	 */
	private static void count(SortingNetwork sn){
		if(map){
			sn.printNetwork();
		}
		long t1 = System.currentTimeMillis();
		sn.doAllTransitions(threads);
		long t2 = System.currentTimeMillis();
		if(time){
			System.out.println("Transitions time = "+(t2-t1)+" ms");
		}
		System.out.println();
		sn.printOutput();
	}
}
